package com.hnichr.ump.schedule.job;


import com.hnichr.ump.common.schedule.Constants;
import com.hnichr.ump.common.schedule.dto.RunResultDTO;
import com.hnichr.ump.common.schedule.entity.ScheduleDesk;
import com.hnichr.ump.common.schedule.entity.ScheduleLog;
import com.hnichr.ump.schedule.ScheduleTask;
import com.hnichr.ump.schedule.service.ScheduleDeskService;
import com.hnichr.ump.schedule.service.ScheduleLogService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

public abstract class AbstractJob implements Job{

    private static final Logger logger = LoggerFactory.getLogger(AbstractJob.class);

    @Value("${schedule.enabled}")
    private boolean scheduleEnabled;

    @Autowired
    private ScheduleDeskService scheduleDeskService;

    @Autowired
    private ScheduleLogService scheduleLogService;

    /**
     * 运行条件检查，返回true继续运行
     * @return
     */
    @Override
    @Transactional
    public boolean runCheck(ScheduleDesk scheduleDesk){
        if(scheduleDesk==null|| !StringUtils.equals(Constants.OpenStatus.OPEN.getCode(),scheduleDesk.getOpenStatus())||
                !StringUtils.equals(Constants.RunningStatus.IDLE.getCode(),scheduleDesk.getRunningStatus())){
            return false;
        }
        return doRunCheck(scheduleDesk);
    }

    @Override
    public void run(){
        //判断定时任务是否打开
        if(!scheduleEnabled){
            logger.info(">>>>>>定时任务关闭，任务执行取消");
            return;
        }
        logger.info("AbstractJob::run 开始执行");
        String scheduleName = getScheduleName();
        ScheduleDesk scheduleDesk = scheduleDeskService.getByScheduleName(scheduleName);
        if(!runCheck(scheduleDesk)){
            return;
        }
        scheduleDesk.setRunningStatus(Constants.RunningStatus.RUNNING.getCode());
        scheduleDeskService.update(scheduleDesk);
        ScheduleLog scheduleLog = new ScheduleLog();
        scheduleLog.setScheduleName(scheduleName);
        scheduleLog.setStartTime(new Date());
        try{
            RunResultDTO runResult = doRun(scheduleDesk);
            scheduleLog.setRunResult(runResult.getResult().getCode());
            scheduleLog.setErrorMessage(runResult.getMessage());
            //如果成功，更新下次调度时间
            if(runResult.getResult() == Constants.RunResult.SUCCESS){
                scheduleDesk.setScheduleTime(getNextScheduleTime(scheduleDesk));
            }
        }
        catch (Exception e){
            scheduleLog.setRunResult(Constants.RunResult.FAILED.getCode());
            scheduleLog.setErrorMessage(e.getMessage());
            logger.error(">>>>>>>>>>>>>>>{}执行失败",scheduleName,e);
        }
        scheduleLog.setEndTime(new Date());
        scheduleLogService.save(scheduleLog);

        scheduleDesk.setRunningStatus(Constants.RunningStatus.IDLE.getCode());
        scheduleDeskService.update(scheduleDesk);
    }
}
